#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "ctype.h"
#include "parameters.h"
#include "version.h"
#include "esp_system.h"
#include "esp_mac.h"
#include "esp_wifi.h"
#include "DevicesTime.h"
#include "gatts_table.h"
#include "softap_sta.h"
#include "DriverOTA.h"
#include "FeedPhy.h"
#include "FeedFrame.h"
#include "FeedID.h"


/* 获取字符串内 字母、数字、标点符号等非空格 的字符串长度 */
static int32_t iStrNGraphLen(char *pcName, int32_t iLength)
{
    int32_t i;

    for(i = 0; i < iLength; ++i)
    {
        if(isgraph((int)pcName[i]) == 0)
            break;
    }

    return i;
}

/* 获取字符串内 ASCII 编码的字母或数字 的字符串长度 */
static int32_t iStrNAlnumLen(char *pcName, int32_t iLength)
{
    int32_t i;

    for(i = 0; i < iLength; ++i)
    {
        if(isalnum((int)pcName[i]) == 0)
            break;
    }

    return i;
}

static int8_t cFeedIDHeartbeat(void *pvDatas)
{
    static uint32_t st_uiCnt = 0;
    uint32_t uiCnt;
    FeedFrameType *ptypeFrame = pvDatas;
    int32_t i;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_INT) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length > 4) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        for(i = 0, uiCnt = st_uiCnt++; ((uiCnt != 0) || (i == 0)); uiCnt >>= 8, ++i)
        {
            ptypeFrame->datas[i] = uiCnt;
        }

        ptypeFrame->length = i;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }

    return 0;
}

static int8_t cFeedIDSystemState(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_INT) && (ptypeFrame->length == 1))
        {
            if(ptypeFrame->datas[0] & 0x08)
            {
                cParametersDeinit();
                cParametersSave();
                esp_restart();
            }

            if(ptypeFrame->datas[0] & 0x01)
            {
                esp_restart();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_INT) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length != 1) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->datas[0] = 0;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }

    return 0;
}

static int8_t cFeedIDNetworkState(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_INT) && (ptypeFrame->length == 1))
        {
            if(ptypeFrame->datas[0] & 0x01)
            {
                ptypeParameters->networkState |= BIT0;
                esp_wifi_disconnect();
                wifi_init_softap(ptypeParameters->WIFI_AP_SSID, ptypeParameters->WIFI_AP_PASSWORD);
                wifi_init_sta(ptypeParameters->WIFI_STA_SSID, ptypeParameters->WIFI_STA_PASSWORD);
                esp_wifi_connect();
            }
            else
            {
                ptypeParameters->networkState &= ~BIT0;
            }

            /* 保存参数 */
            cParametersSave();
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_INT) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length != 1) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->datas[0] = ptypeParameters->networkState;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }

    return 0;
}

static int8_t cFeedIDTime(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    int64_t lTime;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_RAW) && (ptypeFrame->length == 9))
        {
            memcpy(&lTime, ptypeFrame->datas, 8);
            vTimestampSet(lTime);

            vTimeUTCSet(ptypeFrame->datas[8] * 0.1f);
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_RAW) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length != 9) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        lTime = lTimestampGet();
        memcpy(ptypeFrame->datas, &lTime, 8);

        ptypeFrame->datas[8] = fTimeUTCGet() * 10.0f;
        ptypeFrame->length = 9;
        ptypeFrame->type = FEED_FRAME_TYPE_RAW;
    }

    return 0;
}

static int8_t cFeedIDFrameIotMax(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iValue, i;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        ptypeFrame->datas[0] = FEED_FRAME_ERROR_ACCESS;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        for(i = 0, iValue = ptypeParameters->frameIotMax; ((iValue != 0) || (i == 0)); iValue >>= 8)
        {
            ptypeFrame->datas[i++] = iValue;
        }

        ptypeFrame->length = i;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }

    return 0;
}

static int8_t cFeedIDFrameMcuMax(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iValue, i;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_INT) && (ptypeFrame->length <= 2))
        {
            for(iValue = 0, i = 0; i < ptypeFrame->length; ++i)
            {
                iValue |= (uint32_t)ptypeFrame->datas[i] << (8 * i);
            }
            ptypeParameters->frameMcuMax = iValue;
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_INT) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length > 2) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        for(i = 0, iValue = ptypeParameters->frameMcuMax; ((iValue != 0) || (i == 0)); iValue >>= 8)
        {
            ptypeFrame->datas[i++] = iValue;
        }

        ptypeFrame->length = i;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }

    return 0;
}

static int8_t cFeedIDIotVersionHard(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        ptypeFrame->datas[0] = FEED_FRAME_ERROR_ACCESS;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(pcVersionAPPHardGet());
        memcpy(ptypeFrame->datas, pcVersionAPPHardGet(), ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDIotVersionSoft(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        ptypeFrame->datas[0] = FEED_FRAME_ERROR_ACCESS;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(pcVersionAPPSoftGet());
        memcpy(ptypeFrame->datas, pcVersionAPPSoftGet(), ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDMcuVersionHard(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length < sizeof(ptypeParameters->VERSION_HARD_MCU)))
        {
            strcpy(ptypeParameters->VERSION_HARD_MCU, (char *)ptypeFrame->datas);
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length >= sizeof(ptypeParameters->VERSION_HARD_MCU)) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(ptypeParameters->VERSION_HARD_MCU);
        memcpy(ptypeFrame->datas, ptypeParameters->VERSION_HARD_MCU, ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDMcuVersionSoft(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length < sizeof(ptypeParameters->VERSION_SOFT_MCU)))
        {
            strcpy(ptypeParameters->VERSION_SOFT_MCU, (char *)ptypeFrame->datas);
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length >= sizeof(ptypeParameters->VERSION_SOFT_MCU)) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(ptypeParameters->VERSION_SOFT_MCU);
        memcpy(ptypeFrame->datas, ptypeParameters->VERSION_SOFT_MCU, ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDIotPID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length < sizeof(ptypeParameters->PID)))
        {
            if((iLength = iStrNAlnumLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->PID, 0, sizeof(ptypeParameters->PID));
                memcpy(ptypeParameters->PID, ptypeFrame->datas, ptypeFrame->length);
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length >= sizeof(ptypeParameters->UID_DRIVER)) ? FEED_FRAME_ERROR_LENGTH :
                               (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(ptypeParameters->PID);
        memcpy(ptypeFrame->datas, ptypeParameters->PID, ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDIotUID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        ptypeFrame->datas[0] = FEED_FRAME_ERROR_ACCESS;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(ptypeParameters->UID);
        memcpy(ptypeFrame->datas, ptypeParameters->UID, ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDMcuUID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length < sizeof(ptypeParameters->UID_DRIVER)))
        {
            if((iLength = iStrNAlnumLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->UID_DRIVER, 0, sizeof(ptypeParameters->UID_DRIVER));
                memcpy(ptypeParameters->UID_DRIVER, ptypeFrame->datas, ptypeFrame->length);
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length >= sizeof(ptypeParameters->UID_DRIVER)) ? FEED_FRAME_ERROR_LENGTH :
                               (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(ptypeParameters->UID_DRIVER);
        memcpy(ptypeFrame->datas, ptypeParameters->UID_DRIVER, ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDAppUID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length < sizeof(ptypeParameters->UID_APP)))
        {
            if((iLength = iStrNAlnumLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->UID_APP, 0, sizeof(ptypeParameters->UID_APP));
                memcpy(ptypeParameters->UID_APP, ptypeFrame->datas, ptypeFrame->length);
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length >= sizeof(ptypeParameters->UID_APP)) ? FEED_FRAME_ERROR_LENGTH :
                               (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(ptypeParameters->UID_APP);
        memcpy(ptypeFrame->datas, ptypeParameters->UID_APP, ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDBtMac(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        ptypeFrame->datas[0] = FEED_FRAME_ERROR_ACCESS;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        esp_read_mac(ptypeFrame->datas, ESP_MAC_BT);

        ptypeFrame->length = 6;
        ptypeFrame->type = FEED_FRAME_TYPE_RAW;
    }

    return 0;
}

static int8_t cFeedIDBtSSID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length < sizeof(ptypeParameters->BT_NAME)))
        {
            if((iLength = iStrNGraphLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->BT_NAME, 0, sizeof(ptypeParameters->BT_NAME));
                memcpy(ptypeParameters->BT_NAME, ptypeFrame->datas, ptypeFrame->length);
                /* 保存参数 */
                cParametersSave();
                /* 更新蓝牙名 */
                ble_init();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length >= sizeof(ptypeParameters->BT_NAME)) ? FEED_FRAME_ERROR_LENGTH :
                               (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(ptypeParameters->BT_NAME);
        memcpy(ptypeFrame->datas, ptypeParameters->BT_NAME, ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDWifiMac(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        ptypeFrame->datas[0] = FEED_FRAME_ERROR_ACCESS;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        esp_read_mac(ptypeFrame->datas, ESP_MAC_WIFI_STA);

        ptypeFrame->length = 6;
        ptypeFrame->type = FEED_FRAME_TYPE_RAW;
    }

    return 0;
}

static int8_t cFeedIDWifiStaSSID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length >= 1))
        {
            if((iLength = iStrNGraphLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->WIFI_STA_SSID, 0, sizeof(ptypeParameters->WIFI_STA_SSID));
                memcpy(ptypeParameters->WIFI_STA_SSID, ptypeFrame->datas, ptypeFrame->length);
                cParametersSave();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length < 1) ? FEED_FRAME_ERROR_LENGTH :
                               (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(ptypeParameters->WIFI_STA_SSID);
        memcpy(ptypeFrame->datas, ptypeParameters->WIFI_STA_SSID, ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDWifiStaPassword(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length >= 8))
        {
            if((iLength = iStrNGraphLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->WIFI_STA_PASSWORD, 0, sizeof(ptypeParameters->WIFI_STA_PASSWORD));
                memcpy(ptypeParameters->WIFI_STA_PASSWORD, ptypeFrame->datas, ptypeFrame->length);
                cParametersSave();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length < 8) ? FEED_FRAME_ERROR_LENGTH :
                               (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(ptypeParameters->WIFI_STA_PASSWORD);
        memcpy(ptypeFrame->datas, ptypeParameters->WIFI_STA_PASSWORD, ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDWifiApSSID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length >= 1))
        {
            if((iLength = iStrNGraphLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->WIFI_AP_SSID, 0, sizeof(ptypeParameters->WIFI_AP_SSID));
                memcpy(ptypeParameters->WIFI_AP_SSID, ptypeFrame->datas, ptypeFrame->length);
                cParametersSave();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length < 1) ? FEED_FRAME_ERROR_LENGTH :
                               (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(ptypeParameters->WIFI_AP_SSID);
        memcpy(ptypeFrame->datas, ptypeParameters->WIFI_AP_SSID, ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t cFeedIDWifiApPassword(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length >= 8))
        {
            if((iLength = iStrNGraphLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->WIFI_AP_PASSWORD, 0, sizeof(ptypeParameters->WIFI_AP_PASSWORD));
                memcpy(ptypeParameters->WIFI_AP_PASSWORD, ptypeFrame->datas, ptypeFrame->length);
                cParametersSave();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length < 8) ? FEED_FRAME_ERROR_LENGTH :
                               (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = strlen(ptypeParameters->WIFI_AP_PASSWORD);
        memcpy(ptypeFrame->datas, ptypeParameters->WIFI_AP_PASSWORD, ptypeFrame->length);
        ptypeFrame->type = FEED_FRAME_TYPE_STRING;
    }

    return 0;
}

static int8_t  cFeedIDOtaInfo(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    OTAInfoType *ptypeOTAInfo = ptypeOTAInfoGet();

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_RAW) && (ptypeFrame->length == 6))
        {
            memcpy(&ptypeOTAInfo->size, ptypeFrame->datas, 4);
            memcpy(&ptypeOTAInfo->crc, &ptypeFrame->datas[4], 2);
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_RAW) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length != 6) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        memcpy(ptypeFrame->datas, &ptypeOTAInfo->length, 4);
        memcpy(&ptypeFrame->datas[4], &ptypeOTAInfo->lengthCrc, 2);
        ptypeFrame->length = 6;
        ptypeFrame->type = FEED_FRAME_TYPE_RAW;
    }

    return 0;
}

static int8_t  cFeedIDOtaState(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_INT) && (ptypeFrame->length == 1))
        {
            if(ptypeFrame->datas[0] == 1)
            {
                cOTAStop();

                esp_restart();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_INT) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length != 1) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->datas[0] = 0;
        ptypeFrame->datas[1] = 0;
        ptypeFrame->length = 2;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }

    return 0;
}

static int8_t  cFeedIDOtaDatas(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    uint32_t uiAddr;
    int8_t cError = 1;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_RAW) && (ptypeFrame->length > 4))
        {
            memcpy(&uiAddr, ptypeFrame->datas, 4);

            /* 开始传输 */
            if(uiAddr == 0)
            {
                cOTAStart();
            }

            cError = cOTADatasWrite(uiAddr, &ptypeFrame->datas[4], ptypeFrame->length - 4);
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_RAW) ? FEED_FRAME_ERROR_DATAS_TYPE :
                               (ptypeFrame->length <= 4) ? FEED_FRAME_ERROR_LENGTH :
                               (cError != 0) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        ptypeFrame->length = 0;
    }

    return 0;
}

static int8_t cFeedIDAll(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 更新数据 */
    if((ptypeFrame->get == 0) || (ptypeFrame->response != 0))
    {
        ptypeFrame->datas[0] = FEED_FRAME_ERROR_ACCESS;
        ptypeFrame->length = 1;
        ptypeFrame->type = FEED_FRAME_TYPE_INT;
    }
    /* 回复数据 */
    else
    {
        cFeedIDUploadAll();
        cFeedIDUpload();
        ptypeFrame->length = 0;
        ptypeFrame->response = 1;
    }

    return 0;
}

/* 系统 回调函数列表 */
static FeedIDCallType g_typeFeedID[] = {
    /* 通用协议 */
    {.ID = 0xFFF,   .func = cFeedIDAll},

    {.ID = 0x000,   .func = cFeedIDHeartbeat},
    {.ID = 0x001,   .func = cFeedIDSystemState},
    {.ID = 0x002,   .func = cFeedIDNetworkState},
    {.ID = 0x003,   .func = cFeedIDTime},
    {.ID = 0x004,   .func = cFeedIDFrameIotMax},
    {.ID = 0x005,   .func = cFeedIDFrameMcuMax},

    {.ID = 0x010,   .func = cFeedIDOtaInfo},
    {.ID = 0x011,   .func = cFeedIDOtaState},
    {.ID = 0x012,   .func = cFeedIDOtaDatas},

    {.ID = 0x021,   .func = cFeedIDIotVersionHard},
    {.ID = 0x022,   .func = cFeedIDIotVersionSoft},
    {.ID = 0x029,   .func = cFeedIDMcuVersionHard},
    {.ID = 0x02A,   .func = cFeedIDMcuVersionSoft},

    {.ID = 0x031,   .func = cFeedIDIotPID},
    {.ID = 0x032,   .func = cFeedIDIotUID},
    {.ID = 0x034,   .func = cFeedIDMcuUID},
    {.ID = 0x035,   .func = cFeedIDAppUID},

    {.ID = 0x040,   .func = cFeedIDBtMac},
    {.ID = 0x041,   .func = cFeedIDBtSSID},

    {.ID = 0x048,   .func = cFeedIDWifiMac},
    {.ID = 0x049,   .func = cFeedIDWifiStaSSID},
    {.ID = 0x04A,   .func = cFeedIDWifiStaPassword},
    {.ID = 0x04B,   .func = cFeedIDWifiApSSID},
    {.ID = 0x04C,   .func = cFeedIDWifiApPassword},
};

int8_t cFeedIDUpload(void)
{
    FeedFrameType typeFrame;
    int32_t i;

    typeFrame.get = 1;

    for(i = 0; i < (sizeof(g_typeFeedID) / sizeof(g_typeFeedID[0])); ++i)
    {
        if((g_typeFeedID[i].upload != 0) && (g_typeFeedID[i].ID != 0xFFF))
        {
            g_typeFeedID[i].upload = 0;

            typeFrame.response = 0;
            typeFrame.ID = g_typeFeedID[i].ID;

            /* 更新数据 */
            g_typeFeedID[i].func(&typeFrame);

            if(typeFrame.length > 0)
            {
                typeFrame.response = 1;
                cFeedPhyDatasAdd(&typeFrame, typeFrame.length + 4);
            }
        }
    }

    return 0;
}

int8_t cFeedIDUploadAll(void)
{
    int32_t i;

    for(i = 0; i < (sizeof(g_typeFeedID) / sizeof(g_typeFeedID[0])); ++i)
    {
        g_typeFeedID[i].upload = 1;
    }

    return 0;
}

int8_t cFeedIDDecode(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    int32_t i;

    for(i = 0; i < (sizeof(g_typeFeedID) / sizeof(g_typeFeedID[0])); ++i)
    {
        if(ptypeFrame->ID == g_typeFeedID[i].ID)
        {
            /* 更新、请求数据 */
            if((ptypeFrame->get != 0) || (ptypeFrame->response == 0))
                g_typeFeedID[i].func(ptypeFrame);

            if((ptypeFrame->length > 0) && (ptypeFrame->response == 0) && ((ptypeFrame->get != 0) || (ptypeFrame->needResponse != 0)))
            {
                ptypeFrame->response = 1;
                cFeedPhyDatasAdd(ptypeFrame, ptypeFrame->length + 4);
            }

            return 0;
        }
    }

    return 1;
}
